package cn.xsly.ymcc.service.impl;

import cn.xsly.ymcc.constants.MQConstants;
import cn.xsly.ymcc.domain.CourseOrder;
import cn.xsly.ymcc.domain.CourseOrderItem;
import cn.xsly.ymcc.dto.CourseItemVo;
import cn.xsly.ymcc.dto.CourseOrderVo;
import cn.xsly.ymcc.dto.PayMsgInMQ;
import cn.xsly.ymcc.dto.PayOrderVo;
import cn.xsly.ymcc.fegin.CourseFeginClient;
import cn.xsly.ymcc.mapper.CourseOrderMapper;
import cn.xsly.ymcc.result.JSONResult;
import cn.xsly.ymcc.service.ICourseOrderItemService;
import cn.xsly.ymcc.service.ICourseOrderService;
import cn.xsly.ymcc.util.AssertUtil;
import cn.xsly.ymcc.util.CodeGenerateUtils;
import cn.xsly.ymcc.util.StrUtils;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.client.producer.TransactionSendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author whale
 * @since 2022-11-02
 */
@Service
public class CourseOrderServiceImpl extends ServiceImpl<CourseOrderMapper, CourseOrder> implements ICourseOrderService {
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    @Autowired
    private CourseFeginClient courseFeginClient;
    @Autowired
    private ICourseOrderItemService courseOrderItemService;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public String createTokenForOrder(String ids) {
        String token = StrUtils.getComplexRandomString(3);
        Long loginId = 3l;
        redisTemplate.opsForValue().set(loginId + ":" + ids, token);
        return token;
    }

    @Override
    public String placeOrder(PayOrderVo orderVo) {

        Long loginId = 3l;
        String ids = StringUtils.join(orderVo.getCourseIds(), ",");
        Object o = redisTemplate.opsForValue().get(loginId + ":" + ids);
        AssertUtil.isEqualsTrim(o.toString(), orderVo.getToken(), "订单已存在");

        JSONResult jsonResult = courseFeginClient.orderList(ids);
        AssertUtil.isTrue(jsonResult.isSuccess(), jsonResult.getMessage());
        //json里面获取对象转json字符串，再转对象
        String jsonString = JSON.toJSONString(jsonResult.getData());
        CourseOrderVo courseOrderVo = JSON.parseObject(jsonString, CourseOrderVo.class);
        //4.生成的order
        CourseOrder order = new CourseOrder();
        order.setCreateTime(new Date());
        /*
            订单编号--系统唯一
         */
        String orderSn = CodeGenerateUtils.generateOrderSn(loginId);
        order.setOrderNo(orderSn);
        /**
         * 支付总的价格
         */
        order.setTotalAmount(courseOrderVo.getTotalAmount());
        /**
         * 优惠金额
         */
        order.setDiscountAmount(new BigDecimal("0"));
        /**
         * 支付金额
         */
        order.setPayAmount(order.getTotalAmount().subtract(order.getDiscountAmount()));

        /**
         * 秒杀数量
         */
        order.setTotalCount(1);
        order.setStatusOrder(CourseOrder.PLACE_ORDER_OK);
        order.setUserId(loginId);
        /**
         * 订单标题
         */
        order.setTitle("购买课程下单");
        order.setVersion(0);
        /**
         * 支付方式:0余额直接，1支付宝，2微信,3银联
         */
        order.setPayType(orderVo.getPayType());
        /**
         * 0普通订单 ， 1秒杀订单
         */
        order.setOrderType(orderVo.getType());

       //5.保存数据  返回数据的主键

        List<CourseItemVo> list = courseOrderVo.getCourseInfos();
        list.forEach(courseItemVo -> {
            CourseOrderItem item = new CourseOrderItem();
            item.setAmount(courseItemVo.getCourseMarket().getPrice());
            item.setCount(1);
            item.setCreateTime(new Date());
            item.setCourseId(courseItemVo.getCourse().getId());
            item.setCourseName(courseItemVo.getCourse().getName());
            item.setCoursePic(courseItemVo.getCourse().getPic());
            item.setVersion(0);
            item.setOrderNo(orderSn);
            item.setKillCourseId(0L);
            //item.setOrderId(order.getId());
            //保存订单明细
            //courseOrderItemService.insert(item);
            order.getItems().add(item);
        });
        //发送事务消息
        /*
         * @param txProducerGroup 事务组的名称，监听事务状态 要使用
         * @param destination     目的地 formats: `topicName:tags`
         * @param message         消息体
         * @param arg             额外的参数
         * @return TransactionSendResult
         */
        //封装mq里面消息体
        PayMsgInMQ msgInMQ = new PayMsgInMQ(order.getPayAmount(), order.getPayType(), orderSn, loginId, "", order.getTitle());
        Message<PayMsgInMQ> message = MessageBuilder.withPayload(msgInMQ).build();
        TransactionSendResult sendResult = rocketMQTemplate.sendMessageInTransaction(
                    MQConstants.TX_PRODUCER_ORDER,
                MQConstants.TOPIC_ORDER_TAGS_ORDER, message, order);
        AssertUtil.isTrue(sendResult.getSendStatus().equals(SendStatus.SEND_OK), "消息发送失败");
        //移除redis里面的key
        redisTemplate.delete(loginId + ":" + ids);
        return orderSn;
    }

    @Override
    @Transactional
    public void saveOrderAndItem(CourseOrder order) {
        insert(order);
        List<CourseOrderItem> items = order.getItems();
        items.forEach(item -> {
                    item.setOrderId(order.getId());
                    courseOrderItemService.insert(item);
                }
        );
    }
    @Override
    public CourseOrder selectByOrderSn(String orderNo) {
        Wrapper<CourseOrder> wrapper = new EntityWrapper<>();
        wrapper.eq("order_no",orderNo);
        return  selectOne(wrapper);
    }

    @Override
    public void cancelOrder(String orderSn) {
        //根据订单查询订单
        CourseOrder courseOrder = selectByOrderSn(orderSn);
        //判断订单是否需要取消
        if(courseOrder!=null&&courseOrder.getStatusOrder()==0){
            //超时取消订单
            courseOrder.setStatusOrder(4);
            courseOrder.setUpdateTime(new Date());
            updateById(courseOrder);
        }

    }
}
